package com.tanhua.mongo.api;

import cn.hutool.core.collection.CollUtil;
import com.tanhua.api.service.MovementApi;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.mongo.MovementTimeLine;
import com.tanhua.model.vo.PageResult;
import com.tanhua.mongo.service.MovementTimeLineService;
import com.tanhua.mongo.utils.IdWorker;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.List;

@DubboService
public class MovementApiImpl implements MovementApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private MovementTimeLineService timeLineService;

    @Override
    public void saveMovement(Movement movement) {
        // 补全数据
        movement.setPid(idWorker.getNextId("movement"));

        // 添加动态数据
        mongoTemplate.save(movement);

        // 异步执行时间线表的数据添加
        timeLineService.saveTimeLine(movement);

        /*// 查询当前用户的好友
        List<Friend> friendList = mongoTemplate.find(new Query(
                Criteria.where("userId").is(movement.getUserId())
        ), Friend.class);

        // 遍历好友列表数据，添加时间线数据
        for (Friend friend : friendList) {
            MovementTimeLine movementTimeLine = new MovementTimeLine();
            movementTimeLine.setMovementId(movement.getId());
            movementTimeLine.setCreated(new Date().getTime());
            movementTimeLine.setFriendId(friend.getFriendId());
            movementTimeLine.setUserId(friend.getUserId());

            mongoTemplate.save(movementTimeLine);
        }*/
    }

    @Override
    public PageResult<Movement> findByPageUserId(Integer page, Integer pagesize, Long userId) {

        Query query = new Query(Criteria.where("userId").is(userId));

        // 查询总条数
        long count = mongoTemplate.count(query, Movement.class);

        query.skip((page - 1) * pagesize)
                .limit(pagesize)
                .with(Sort.by(Sort.Order.desc("created")));
        // 分页查询
        List<Movement> movements = mongoTemplate.find(query, Movement.class);

        return new PageResult<>(page, pagesize, count, movements);
    }

    @Override
    public List<Movement> findByFriendIdMovement(Integer page, Integer pagesize, Long userId) {

        // 根据当前用户id,查询时间限表所对应的好友列表
        List<MovementTimeLine> timeLines = mongoTemplate.find(new Query(Criteria.where("friendId").is(userId)), MovementTimeLine.class);

        if (CollUtil.isEmpty(timeLines)) {
            return null;
        }

        // 抽取列表中的动态id
//        List<ObjectId> movementIds = timeLines.stream().map(MovementTimeLine::getMovementId).collect(Collectors.toList());
        List<ObjectId> movementIds = CollUtil.getFieldValues(timeLines, "movementId", ObjectId.class);
        // 根据动态id列表，查询动态数据
        return mongoTemplate.find(new Query(Criteria.where("id").in(movementIds))
                .skip((page - 1) * pagesize)
                .limit(pagesize)
                .with(Sort.by(Sort.Order.desc("created"))),Movement.class);
    }

    @Override
    public List<Movement> randomMovements(Integer pagesize) {

        // 随机生成10条数据
        TypedAggregation aggregation = Aggregation.newAggregation(Movement.class, Aggregation.sample(10));


        AggregationResults<Movement> aggregate = mongoTemplate.aggregate(aggregation, Movement.class);

        return aggregate.getMappedResults();
    }

    @Override
    public List<Movement> findByPids(List<Long> collect) {
        return mongoTemplate.find(new Query(
                Criteria.where("pid").in(collect)
        ), Movement.class);
    }

    @Override
    public Movement findById(String movementId) {
        return mongoTemplate.findById(new ObjectId(movementId), Movement.class);
    }

    @Override
    public PageResult<Movement> findByPageMovement(Integer page, Integer pagesize, Long uid, Integer state) {
        Criteria criteria = Criteria.where("userId").is(uid);
        if (state != null) {
            criteria.and("state").is(state);
        }

        long count = mongoTemplate.count(Query.query(criteria), Movement.class);

        Query query = new Query(criteria)
                .skip((page - 1) * pagesize)
                .limit(pagesize)
                .with(Sort.by(Sort.Order.desc("created")));

        List<Movement> movementList = mongoTemplate.find(query, Movement.class);

        return new PageResult<>(page, pagesize, count, movementList);
    }
}
